package com.infore.statisticsAndAlarm.service.impl;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.apache.commons.lang.math.NumberUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import com.infore.statisticsAndAlarm.bo.DatasChartsBo;
import com.infore.statisticsAndAlarm.constant.Constants;
import com.infore.statisticsAndAlarm.entity.DayData;
import com.infore.statisticsAndAlarm.entity.MonthData;
import com.infore.statisticsAndAlarm.entity.QuarterData;
import com.infore.statisticsAndAlarm.entity.WeekData;
import com.infore.statisticsAndAlarm.entity.YearData;
import com.infore.statisticsAndAlarm.enums.ResultStatus;
import com.infore.statisticsAndAlarm.externalInterface.IDataReceivingService;
import com.infore.statisticsAndAlarm.externalInterface.IStieMangementService;
import com.infore.statisticsAndAlarm.outsideEntity.HourData;
import com.infore.statisticsAndAlarm.outsideEntity.Project;
import com.infore.statisticsAndAlarm.repository.IDayDataRepository;
import com.infore.statisticsAndAlarm.repository.IMonthDataRepository;
import com.infore.statisticsAndAlarm.repository.IQuarterDataRepository;
import com.infore.statisticsAndAlarm.repository.IWeekDataRespository;
import com.infore.statisticsAndAlarm.repository.IYearDataRepository;
import com.infore.statisticsAndAlarm.select.dto.QueryParamDto;
import com.infore.statisticsAndAlarm.service.ICheckingDatasService;
import com.infore.statisticsAndAlarm.service.IDataCharsService;
import com.infore.statisticsAndAlarm.util.ArrayUtils;
import com.infore.statisticsAndAlarm.util.DateUtil;
import com.infore.statisticsAndAlarm.util.JsonUtils;
import com.infore.statisticsAndAlarm.util.MyBeanUtils;
import com.infore.statisticsAndAlarm.util.ObjectMapperUtil;
import com.infore.statisticsAndAlarm.util.ResultEntity;
import com.infore.statisticsAndAlarm.util.ScaleUtil;
import com.infore.statisticsAndAlarm.util.WaterLevelUtils;
import com.infore.statisticsAndAlarm.util.WaterQualityUtil;
import com.infore.statisticsAndAlarm.vo.ChartsVo;

@Service
public class DataCharsServiceImpl implements IDataCharsService {

	@Autowired
	private IDataReceivingService iDataReceivingService;
	@Autowired
	private ObjectMapperUtil ObjectMapperUtil;
	@Autowired
	private IStieMangementService iStieMangementService;
	@Autowired
	private IDayDataRepository iDayDataRepository;
	@Autowired
	private IMonthDataRepository iMonthDataRepository;
	@Autowired
	private IQuarterDataRepository iQuarterDataRepository;
	@Autowired
	private IYearDataRepository iYearDataRepository;
	@Autowired
	private ICheckingDatasService iCheckingDatasService;
	@Autowired
	private IWeekDataRespository iWeekDataRespository;
	@Autowired
	private WaterLevelUtils WaterLevelUtils;

	@SuppressWarnings("unchecked")
	public ResultEntity singleHourDatasChars(DatasChartsBo bo) {
		String stationCode = bo.getStationCode();
		String factorCode = bo.getFactorCode();
		String startTime = bo.getStartTime();
		String endTime = bo.getEndTime();
		// 初始化echarts实体
		ChartsVo chartsVo = new ChartsVo();
		List<String> xAxis = new ArrayList<String>(); // X轴数据集
		List<String> legend = new ArrayList<String>(); // 图例数据集
		List<Map<String, Object>> series = new ArrayList<Map<String, Object>>(); // 系列列表数据集
		// 获取小时基础数据
		ResultEntity resultEntity = iDataReceivingService.queryHourDatas(stationCode, factorCode, startTime, endTime);
		List<HourData> hourDataList = ObjectMapperUtil.convertList(resultEntity, HourData.class);
		if (hourDataList == null || hourDataList.size() == 0) {
			return new ResultEntity(ResultStatus.SUCCESS, Constants.QUERY_SUCCESS);
		}
		List<String> factorCodeList = ArrayUtils.stringToList(factorCode); // 获取因子编码数据集
		ResultEntity projectResultEntity = iStieMangementService.queryProjectByProjectCode();
		Map<String, Project> projectMap = null;
		if (projectResultEntity.getCode() == 0) {
			projectMap = (Map<String, Project>) ((Map<String, Project>) projectResultEntity.getContent()).get("info");
		}
		// 获取初始时间数据集(需要与查询出来的时间数据集进行匹配对数值补null)
		List<String> timeList = DateUtil.getTimeList(startTime, endTime, DateUtil.DATE_SMALL_YMDHH, "hour");
		for (String code : factorCodeList) {
			String projectName = "";
			String projectUnit = "";
			if (projectMap != null) {
				Project project = MyBeanUtils.convertMapToBean((Map<String, Object>) projectMap.get(code),
						Project.class);
				projectName = project.getProjectName();
				projectUnit = project.getProjectUnit();
				String decimalDigits = project.getDecimalDigits() == null ? "3" : project.getDecimalDigits();// 数据修约位数默认为3
				xAxis = new ArrayList<String>(); // X轴数据集
				List<Double> data = new ArrayList<Double>(); // series中的data数据集
				Map<String, Object> seriesMap = new HashMap<String, Object>(); // series中的每个对象
				legend.add(projectName); // 需要存放因子名称
				xAxis = hourDataList.stream().filter(l -> code.equals(l.getFactorCode()))
						.map(l -> DateUtil.dateToString(l.getDataTime(), DateUtil.DATE_SMALL_YMDHH))
						.collect(Collectors.toList());
				data = hourDataList.stream().filter(l -> code.equals(l.getFactorCode()))
						.map(l -> Double.valueOf(ScaleUtil.sciCalProjectString(l.getValue(), decimalDigits)))
						.collect(Collectors.toList());
				// 对数据进行null补值(某个时间点没有值)
				for (int i = 0; i < timeList.size(); i++) {
					if (!xAxis.contains(timeList.get(i))) {
						data.add(i, null);
					}
				}
				seriesMap.put("code", code);
				seriesMap.put("name", projectName);
				seriesMap.put("unit", projectUnit);
				seriesMap.put("data", data);
				seriesMap.put("type", "line");
				series.add(seriesMap);
			}
		}
		chartsVo.setLegend(legend);
		chartsVo.setxAxis(timeList);
		chartsVo.setSeries(series);
		return new ResultEntity(ResultStatus.SUCCESS, Constants.QUERY_SUCCESS).setInfo(chartsVo);
	}

	@SuppressWarnings("unchecked")
	public ResultEntity scatterPointCharts(DatasChartsBo bo) {
		// 先校验站点编码和因子编码不能为空
		ResultEntity resultEntityBo = iCheckingDatasService.ckeckingDatasChartsBo(bo);
		if (!"success".equals(resultEntityBo.getMessage())) {
			return resultEntityBo;
		}
		String stationCode = bo.getStationCode();
		String factorCode = bo.getFactorCode();
		String startTime = bo.getStartTime();
		String endTime = bo.getEndTime();
		// 初始化echarts实体
		ChartsVo chartsVo = new ChartsVo();
		List<String> xAxis = new ArrayList<String>(); // X轴数据集
		List<String> legend = new ArrayList<String>(); // 图例数据集
		List<Map<String, Object>> series = new ArrayList<Map<String, Object>>(); // 系列列表数据集
		// 获取小时基础数据
		ResultEntity resultEntity = iDataReceivingService.queryHourDatas(stationCode, factorCode, startTime, endTime);
		List<HourData> hourDataList = ObjectMapperUtil.convertList(resultEntity, HourData.class);
		if (hourDataList == null || hourDataList.size() == 0) {
			return new ResultEntity(ResultStatus.SUCCESS, Constants.QUERY_SUCCESS);
		}
		List<String> factorCodeList = ArrayUtils.stringToList(factorCode); // 获取因子编码数据集
		ResultEntity projectResultEntity = iStieMangementService.queryProjectByProjectCode();
		Map<String, Project> projectMap = null;
		if (projectResultEntity.getCode() == 0) {
			projectMap = (Map<String, Project>) ((Map<String, Project>) projectResultEntity.getContent()).get("info");
		}
		// 获取初始时间数据集(需要与查询出来的时间数据集进行匹配对数值补null)
		List<String> timeList = DateUtil.getTimeList(startTime, endTime, DateUtil.DATE_SMALL_YMDHH, "hour");
		for (String code : factorCodeList) {
			String projectName = "";
			if (projectMap != null) {
				Project project = MyBeanUtils.convertMapToBean((Map<String, Object>) projectMap.get(code),
						Project.class);
				projectName = project.getProjectName();
				String decimalDigits = project.getDecimalDigits() == null ? "3" : project.getDecimalDigits();
				xAxis = new ArrayList<String>(); // X轴数据集
				List<Double> dataValue = new ArrayList<Double>(); // series中的data数据集
				List<List<Double>> singleData = new ArrayList<List<Double>>();
				Map<String, Object> seriesMap = new HashMap<String, Object>(); // series中的每个对象
				legend.add(projectName); // 需要存放因子名称
				xAxis = hourDataList.stream().filter(l -> code.equals(l.getFactorCode()))
						.map(l -> DateUtil.dateToString(l.getDataTime(), DateUtil.DATE_SMALL_YMDHH))
						.collect(Collectors.toList());
				dataValue = hourDataList.stream().filter(l -> code.equals(l.getFactorCode()))
						.map(l -> Double.valueOf(ScaleUtil.sciCalProjectString(l.getValue().toString(), decimalDigits)))
						.collect(Collectors.toList());
				for (int i = 0; i < xAxis.size(); i++) {
					List<Double> data = new ArrayList<Double>(); // series中的data数据集
					data.add(Double.valueOf(i + ""));
					data.add(dataValue.get(i));
					singleData.add(data);
				}
				// 对数据进行null补值(某个时间点没有值)
				for (int i = 0; i < timeList.size(); i++) {
					if (!xAxis.contains(timeList.get(i))) {
						singleData.add(i, null);
					}
				}
				seriesMap.put("name", projectName);
				seriesMap.put("type", "scatter");
				seriesMap.put("data", singleData);
				series.add(seriesMap);
			}
		}
		chartsVo.setLegend(legend);
		chartsVo.setxAxis(timeList);
		chartsVo.setSeries(series);
		return new ResultEntity(ResultStatus.SUCCESS, Constants.QUERY_SUCCESS).setInfo(chartsVo);
	}

	// 对比图中查询分发
	public ResultEntity compareDatasCharts(DatasChartsBo bo) {
		// 验证查询信息的合法性
		ResultEntity resultEntityBo = iCheckingDatasService.ckeckingDatasChartsBo(bo);
		if (!"success".equals(resultEntityBo.getMessage())) {
			return resultEntityBo;
		}
		String type = bo.getType();
		ResultEntity resultEntity = new ResultEntity();
		String startTime = "";
		String endTime = "";
		// 查询一天之内的信息
//		if ("day".equals(type)) {
//			startTime = bo.getStartTime() + " 00:00:00";
//			endTime = bo.getEndTime() + " 23:59:59";
//			bo.setStartTime(startTime);
//			bo.setEndTime(endTime);
//			resultEntity = singleHourDatasChars(bo);
		// 查询一个月之内的信息
//		}
		if ("day".equals(type)) {
//			startTime = bo.getStartTime() + "-01";
//			Date endDate1 = DateUtil.stringToDate(bo.getEndTime(), DateUtil.DATE_SMALL_YM);
//			endTime = DateUtil.getLastDayM(endDate1,DateUtil.DATE_SMALL_STR);//得到当月最后一天
//			bo.setStartTime(startTime);
//			bo.setEndTime(endTime);
			resultEntity = singleDayDatasCharts(bo);
			// 一年查询12个月之内的信息
		} else if ("month".equals(type)) {
//			startTime = bo.getStartTime() + "-01";
//			endTime = bo.getEndTime() + "-12";
//			bo.setStartTime(startTime);
//			bo.setEndTime(endTime);
			startTime = bo.getStartTime() + "-01";
			Date endDate1 = DateUtil.stringToDate(bo.getEndTime(), DateUtil.DATE_SMALL_YM);
			endTime = DateUtil.getLastDayM(endDate1, DateUtil.DATE_SMALL_STR);// 得到当月最后一天
			bo.setStartTime(startTime);
			bo.setEndTime(endTime);
			resultEntity = singleDayDatasCharts(bo);
			// 一季度查询3个月之内的信息
		} else if ("quarter".equals(type)) {
			String str1 = "-01";
			String str2 = "-12";
			switch (bo.getStartQuarter()) {
			case "1":
				str2 = "-03";
				break;
			case "2":
				str1 = "-04";
				str2 = "-06";
				break;
			case "3":
				str1 = "-07";
				str2 = "-09";
				break;
			case "4":
				str1 = "-10";
				break;
			default:
				break;
			}
			startTime = bo.getStartTime() + str1;
			endTime = bo.getEndTime() + str2;
			bo.setStartTime(startTime);
			bo.setEndTime(endTime);
			resultEntity = singleMonthDatasCharts(bo);
		} else if ("year".equals(type)) {
			startTime = bo.getStartTime() + "-01";
			endTime = bo.getEndTime() + "-12";
			bo.setStartTime(startTime);
			bo.setEndTime(endTime);
			resultEntity = singleMonthDatasCharts(bo);
		} else {
			resultEntity = new ResultEntity(ResultStatus.SUCCESS, "暂无数据信息");
		}
		return resultEntity;
	}

	public ResultEntity annualRatioCharts(DatasChartsBo bo) {
		// 先校验站点编码和因子编码不能为空
		ResultEntity resultEntityBo = iCheckingDatasService.ckeckingDatasChartsBo(bo);
		if (!"success".equals(resultEntityBo.getMessage())) {
			return resultEntityBo;
		}
		// 得到当前时间段内的信息
		ResultEntity resultEntity = compareDatasCharts(bo);
		ChartsVo vo = new ChartsVo();
		if (resultEntity.getContent() != null) {
			vo = ObjectMapperUtil.convertObject(resultEntity, ChartsVo.class);
		}
		// 获取比较时间段内的因子信息
		bo.setStartTime(bo.getCompareStart());
		bo.setEndTime(bo.getCompareEnd());
		if ("quarter".equals(bo.getType())) {
			bo.setStartQuarter(bo.getEndQuarter());
		}
		ResultEntity compareResult = compareDatasCharts(bo);
		ChartsVo compareVo = new ChartsVo();
		if (compareResult.getContent() != null) {
			compareVo = ObjectMapperUtil.convertObject(compareResult, ChartsVo.class);
		}
		// 得到对比的数据图表信息
		List<Map<String, Object>> seriesCompare = compareVo.getSeries();
		Map<String, Object> seriesMapCompare = new HashMap<String, Object>(); // 对比中series中的每个对象
		Map<String, Object> seriesMap = new HashMap<String, Object>(); // series中的每个对象
		// 如果哪一种数据（本期/对比期）有空数据则不修改
		if (seriesCompare != null) {
			seriesMapCompare = seriesCompare.get(0);
			String dataNameCompare = (String) seriesMapCompare.get("name");
			seriesMapCompare.replace("name", "对比" + dataNameCompare + "值");
			// 修改本期数据图表名称
			List<Map<String, Object>> series = vo.getSeries();
			if (series != null && vo != null) {
				seriesMap = series.get(0);
				String dataName = (String) seriesMap.get("name");
				seriesMap.replace("name", "本期" + dataName + "值");
				series.add(seriesMapCompare);
			} else {
				return new ResultEntity(ResultStatus.SUCCESS, Constants.QUERY_SUCCESS).setInfo(compareVo);
			}
		} else {
			List<Map<String, Object>> series = vo.getSeries();
			if (series != null && vo != null) {
				seriesMap = series.get(0);
				String dataName = (String) seriesMap.get("name");
				seriesMap.replace("name", "本期" + dataName + "值");
				return new ResultEntity(ResultStatus.SUCCESS, Constants.QUERY_SUCCESS).setInfo(vo);
			}else {
				return new ResultEntity(ResultStatus.SUCCESS, Constants.QUERY_SUCCESS);
			}
		}
		return new ResultEntity(ResultStatus.SUCCESS, Constants.QUERY_SUCCESS).setInfo(vo);
	}

	@SuppressWarnings("unchecked")
	public ResultEntity singleDatablockCharts(DatasChartsBo bo) {
		// 先校验站点编码和因子编码不能为空
		ResultEntity resultEntityBo = iCheckingDatasService.ckeckingDatasChartsBo(bo);
		if (!"success".equals(resultEntityBo.getMessage())) {
			return resultEntityBo;
		}
		// 获取数据库里面的日数据信息
		List<String> stationCode = ArrayUtils.stringToList(bo.getStationCode());
		List<String> factorCode = ArrayUtils.stringToList(bo.getFactorCode());
		Date startDate = DateUtil.stringToDate(bo.getStartTime(), DateUtil.DATE_SMALL_STR);
		Date endDate = DateUtil.stringToDate(bo.getEndTime(), DateUtil.DATE_SMALL_STR);
		List<DayData> dayDatas = iDayDataRepository
				.findByStationCodeInAndFactorCodeInAndDataTimeBetweenOrderByDataTimeAsc(stationCode, factorCode,
						startDate, endDate);
		// 封装echarts实体类
		ChartsVo vo = new ChartsVo();
		List<String> xAxis = new ArrayList<String>(); // X轴数据集
		List<String> legend = new ArrayList<String>(); // 图例数据集
		List<Map<String, Object>> series = new ArrayList<Map<String, Object>>(); // 系列列表数据集
		// 获取因子编码
		ResultEntity projectResultEntity = iStieMangementService.queryProjectByProjectCode();
		Map<String, Project> projectMap = null;
		if (projectResultEntity.getCode() == 0) {
			projectMap = (Map<String, Project>) ((Map<String, Project>) projectResultEntity.getContent()).get("info");
		}
		// 获取完整的时间区间
		List<String> timeList = DateUtil.getTimeList(bo.getStartTime(), bo.getEndTime(), DateUtil.DATE_SMALL_STR,
				"day");
		for (String factor : factorCode) {
			String projectName = "";
			if (projectMap != null) {
				Project project = MyBeanUtils.convertMapToBean((Map<String, Object>) projectMap.get(factor),
						Project.class);
				projectName = project.getProjectName();
			}
			legend.add(projectName);
			Map<String, Object> seriesMax = new HashMap<String, Object>(); // series中的每个对象
			Map<String, Object> seriesMin = new HashMap<String, Object>(); // series中的每个对象
			Map<String, Object> seriesAvg = new HashMap<String, Object>(); // series中的每个对象
			List<String> dataMax = new ArrayList<String>();// 最大值
			List<String> dataMin = new ArrayList<String>();// 最小值
			List<String> dataAvg = new ArrayList<String>();// 平均值
			xAxis = dayDatas.stream().filter(t -> t.getFactorCode().equals(factor))
					.map(t -> DateUtil.dateToString(t.getDataTime(), DateUtil.DATE_SMALL_STR))
					.collect(Collectors.toList());
			dataMax = dayDatas.stream().filter(t -> t.getFactorCode().equals(factor)).map(t -> t.getDataValueMax())
					.collect(Collectors.toList());
			dataMin = dayDatas.stream().filter(t -> t.getFactorCode().equals(factor)).map(t -> t.getDataValueMin())
					.collect(Collectors.toList());
			dataAvg = dayDatas.stream().filter(t -> t.getFactorCode().equals(factor)).map(t -> t.getDataValueAvg())
					.collect(Collectors.toList());
			for (int i = 0; i < timeList.size(); i++) {
				if (!xAxis.contains(timeList.get(i))) {
					dataMax.add(i, null);
					dataAvg.add(i, null);
					dataMin.add(i, null);
				}
			}
			seriesMax.put("name", projectName + "最大值");
			seriesMax.put("type", "line");
			seriesMax.put("data", dataMax);
			seriesMin.put("name", projectName + "最小值");
			seriesMin.put("type", "line");
			seriesMin.put("data", dataMin);
			seriesAvg.put("name", projectName + "平均值");
			seriesAvg.put("type", "line");
			seriesAvg.put("data", dataAvg);
			series.add(seriesAvg);
			series.add(seriesMin);
			series.add(seriesMax);
		}
		vo.setLegend(legend);
		vo.setxAxis(timeList);
		vo.setSeries(series);
		return new ResultEntity(ResultStatus.SUCCESS, Constants.QUERY_SUCCESS).setInfo(vo);
	}

	public ResultEntity singleDatasCharts(DatasChartsBo bo) {
		// 验证查询信息的合法性
		ResultEntity resultEntityBo = iCheckingDatasService.ckeckingDatasChartsBo(bo);
		if (!"success".equals(resultEntityBo.getMessage())) {
			return resultEntityBo;
		}
		String type = bo.getType();
		ResultEntity resultEntity = new ResultEntity();
		if ("hour".equals(type)) {
			resultEntity = singleHourDatasChars(bo);
		} else if ("day".equals(type)) {
			resultEntity = singleDayDatasCharts(bo);
		} else if ("month".equals(type)) {
			resultEntity = singleMonthDatasCharts(bo);
		} else if ("quarter".equals(type)) {
			resultEntity = singleQuarterDatasCharts(bo);
		} else if ("year".equals(type)) {
			resultEntity = singleYearDatasCharts(bo);
		}else if("week".equals(type)) {
			resultEntity = singleWeekDatasCharts(bo);
		} else {
			resultEntity = new ResultEntity(ResultStatus.SUCCESS, "暂无数据信息");
		}
		return resultEntity;
	}

	@SuppressWarnings("unchecked")
	public ResultEntity singleDayDatasCharts(DatasChartsBo bo) {// 单因子天数据
		String stationCode = bo.getStationCode();
		String factorCode = bo.getFactorCode();
		String startTime = bo.getStartTime();
		String endTime = bo.getEndTime();
		List<String> stationCodeList = ArrayUtils.stringToList(stationCode);
		List<String> factorCodeList = ArrayUtils.stringToList(factorCode); // 获取因子编码数据集
		Date startDate = DateUtil.stringToDate(bo.getStartTime(), DateUtil.DATE_SMALL_STR);
		Date endDate = DateUtil.stringToDate(bo.getEndTime(), DateUtil.DATE_SMALL_STR);
		// 初始化echarts实体
		ChartsVo chartsVo = new ChartsVo();
		List<String> xAxis = new ArrayList<String>(); // X轴数据集
		List<String> legend = new ArrayList<String>(); // 图例数据集
		List<Map<String, Object>> series = new ArrayList<Map<String, Object>>(); // 系列列表数据集
		// 获取天基础数据
		List<DayData> hourDataList = iDayDataRepository
				.findByStationCodeInAndFactorCodeInAndDataTimeBetweenOrderByDataTimeAsc(stationCodeList, factorCodeList,
						startDate, endDate);
		if (hourDataList == null || hourDataList.size() == 0) {
			return new ResultEntity(ResultStatus.SUCCESS, Constants.QUERY_SUCCESS);
		}
		ResultEntity projectResultEntity = iStieMangementService.queryProjectByProjectCode();
		Map<String, Project> projectMap = null;
		if (projectResultEntity.getCode() == 0) {
			projectMap = (Map<String, Project>) ((Map<String, Project>) projectResultEntity.getContent()).get("info");
		}
		// 获取初始时间数据集(需要与查询出来的时间数据集进行匹配对数值补null)
		List<String> timeList = DateUtil.getTimeList(startTime, endTime, DateUtil.DATE_SMALL_STR, "day");
		for (String code : factorCodeList) {
			String projectName = "";
			String projectUnit = "";
			if (projectMap != null) {
				Project project = MyBeanUtils.convertMapToBean((Map<String, Object>) projectMap.get(code),
						Project.class);
				projectName = project.getProjectName();
				projectUnit = project.getProjectUnit();
				String decimalDigits = project.getDecimalDigits() == null ? "3" : project.getDecimalDigits();
				xAxis = new ArrayList<String>(); // X轴数据集
				List<Double> data = new ArrayList<Double>(); // series中的data数据集
				Map<String, Object> seriesMap = new HashMap<String, Object>(); // series中的每个对象
				legend.add(projectName); // 需要存放因子名称
				xAxis = hourDataList.stream().filter(l -> code.equals(l.getFactorCode()))
						.map(l -> DateUtil.dateToString(l.getDataTime(), DateUtil.DATE_SMALL_STR))
						.collect(Collectors.toList());
				data = hourDataList.stream().filter(l -> code.equals(l.getFactorCode()))
						.map(l -> Double.valueOf(ScaleUtil.sciCalProjectString(l.getDataValueAvg(), decimalDigits)))
						.collect(Collectors.toList());
				// 对数据进行null补值(某个时间点没有值)
				for (int i = 0; i < timeList.size(); i++) {
					if (!xAxis.contains(timeList.get(i))) {
						data.add(i, null);
					}
				}
				seriesMap.put("code", code);
				seriesMap.put("unit", projectUnit);
				seriesMap.put("name", projectName);
				seriesMap.put("data", data);
				seriesMap.put("type", "line");
				series.add(seriesMap);
			}
		}
		chartsVo.setLegend(legend);
		chartsVo.setxAxis(timeList);
		chartsVo.setSeries(series);
		return new ResultEntity(ResultStatus.SUCCESS, Constants.QUERY_SUCCESS).setInfo(chartsVo);
	}

	@SuppressWarnings("unchecked")
	public ResultEntity singleMonthDatasCharts(DatasChartsBo bo) {// 单因子月数据
		String stationCode = bo.getStationCode();
		String factorCode = bo.getFactorCode();
		String startTime = bo.getStartTime();
		String endTime = bo.getEndTime();
		List<String> stationCodeList = ArrayUtils.stringToList(stationCode);
		List<String> factorCodeList = ArrayUtils.stringToList(factorCode); // 获取因子编码数据集
		Date startDate = DateUtil.stringToDate(bo.getStartTime(), DateUtil.DATE_SMALL_YM);
		Date endDate = DateUtil.stringToDate(bo.getEndTime(), DateUtil.DATE_SMALL_YM);
		// 初始化echarts实体
		ChartsVo chartsVo = new ChartsVo();
		List<String> xAxis = new ArrayList<String>(); // X轴数据集
		List<String> legend = new ArrayList<String>(); // 图例数据集
		List<Map<String, Object>> series = new ArrayList<Map<String, Object>>(); // 系列列表数据集
		// 获取天基础数据
		List<MonthData> hourDataList = iMonthDataRepository
				.findByStationCodeInAndFactorCodeInAndDataTimeBetweenOrderByDataTimeAsc(stationCodeList, factorCodeList,
						startDate, endDate);
		if (hourDataList == null || hourDataList.size() == 0) {
			return new ResultEntity(ResultStatus.SUCCESS, Constants.QUERY_SUCCESS);
		}
		ResultEntity projectResultEntity = iStieMangementService.queryProjectByProjectCode();
		Map<String, Project> projectMap = null;
		if (projectResultEntity.getCode() == 0) {
			projectMap = (Map<String, Project>) ((Map<String, Project>) projectResultEntity.getContent()).get("info");
		}
		// 获取初始时间数据集(需要与查询出来的时间数据集进行匹配对数值补null)
		List<String> timeList = DateUtil.getTimeList(startTime, endTime, DateUtil.DATE_SMALL_YM, "month");
		for (String code : factorCodeList) {
			String projectName = "";
			String projectUnit = "";
			if (projectMap != null) {
				Project project = MyBeanUtils.convertMapToBean((Map<String, Object>) projectMap.get(code),
						Project.class);
				projectName = project.getProjectName();
				projectUnit = project.getProjectUnit();
				String decimalDigits = project.getDecimalDigits() == null ? "3" : project.getDecimalDigits();
				xAxis = new ArrayList<String>(); // X轴数据集
				List<Double> data = new ArrayList<Double>(); // series中的data数据集
				Map<String, Object> seriesMap = new HashMap<String, Object>(); // series中的每个对象
				legend.add(projectName); // 需要存放因子名称
				xAxis = hourDataList.stream().filter(l -> code.equals(l.getFactorCode()))
						.map(l -> DateUtil.dateToString(l.getDataTime(), DateUtil.DATE_SMALL_YM))
						.collect(Collectors.toList());
				data = hourDataList.stream().filter(l -> code.equals(l.getFactorCode()))
						.map(l -> Double.valueOf(ScaleUtil.sciCalProjectString(l.getDataValueAvg(), decimalDigits)))
						.collect(Collectors.toList());
				// 对数据进行null补值(某个时间点没有值)
				for (int i = 0; i < timeList.size(); i++) {
					if (!xAxis.contains(timeList.get(i))) {
						data.add(i, null);
					}
				}
				seriesMap.put("code", code);
				seriesMap.put("unit", projectUnit);
				seriesMap.put("name", projectName);
				seriesMap.put("data", data);
				seriesMap.put("type", "line");
				series.add(seriesMap);
			}
		}
		chartsVo.setLegend(legend);
		chartsVo.setxAxis(timeList);
		chartsVo.setSeries(series);
		return new ResultEntity(ResultStatus.SUCCESS, Constants.QUERY_SUCCESS).setInfo(chartsVo);
	}

	@SuppressWarnings("unchecked")
	public ResultEntity singleQuarterDatasCharts(DatasChartsBo bo) {// 因子季度数据
		String stationCode = bo.getStationCode();
		String factorCode = bo.getFactorCode();
		// 初始化echarts实体
		ChartsVo chartsVo = new ChartsVo();
		List<String> xAxis = new ArrayList<String>(); // X轴数据集
		List<String> legend = new ArrayList<String>(); // 图例数据集
		List<Map<String, Object>> series = new ArrayList<Map<String, Object>>(); // 系列列表数据集
		// 构建查询条件
		String startYear = bo.getStartTime();
		String startQuarter = bo.getStartQuarter();
		String startTime = startYear + startQuarter;
		String endYear = bo.getEndTime();
		String endQuarter = bo.getEndQuarter();
		String endTime = endYear + endQuarter;
		List<String> stationCodeList = ArrayUtils.stringToList(stationCode);
		List<String> factorCodeList = ArrayUtils.stringToList(factorCode);
		List<QuarterData> hourDataList = iQuarterDataRepository.findAvgInfo(stationCodeList, factorCodeList, startTime,
				endTime);
		if (hourDataList == null || hourDataList.size() == 0) {
			return new ResultEntity(ResultStatus.SUCCESS, Constants.QUERY_SUCCESS);
		}
		ResultEntity projectResultEntity = iStieMangementService.queryProjectByProjectCode();
		Map<String, Project> projectMap = null;
		if (projectResultEntity.getCode() == 0) {
			projectMap = (Map<String, Project>) ((Map<String, Project>) projectResultEntity.getContent()).get("info");
		}
		// 获取初始时间数据集(需要与查询出来的时间数据集进行匹配对数值补null)
		List<String> timeList = DateUtil.getTimeYear(startTime, endTime);
		for (String code : factorCodeList) {
			String projectName = "";
			if (projectMap != null) {
				Project project = MyBeanUtils.convertMapToBean((Map<String, Object>) projectMap.get(code),
						Project.class);
				projectName = project.getProjectName();
				String decimalDigits = project.getDecimalDigits() == null ? "3" : project.getDecimalDigits();
				xAxis = new ArrayList<String>(); // X轴数据集
				List<Double> data = new ArrayList<Double>(); // series中的data数据集
				Map<String, Object> seriesMap = new HashMap<String, Object>(); // series中的每个对象
				legend.add(projectName); // 需要存放因子名称
				xAxis = hourDataList.stream().filter(l -> code.equals(l.getFactorCode())).map(l -> l.getYear())
						.collect(Collectors.toList());
				data = hourDataList.stream().filter(l -> code.equals(l.getFactorCode()))
						.map(l -> Double.valueOf(ScaleUtil.sciCalProjectString(l.getDataValueAvg(), decimalDigits)))
						.collect(Collectors.toList());
				// 对数据进行null补值(某个时间点没有值)
				for (int i = 0; i < timeList.size(); i++) {
					if (!xAxis.contains(timeList.get(i))) {
						data.add(i, null);
					}
				}
				seriesMap.put("code", code);
				seriesMap.put("name", projectName);
				seriesMap.put("data", data);
				seriesMap.put("type", "line");
				series.add(seriesMap);
			}
		}
		chartsVo.setLegend(legend);
		chartsVo.setxAxis(timeList);
		chartsVo.setSeries(series);
		return new ResultEntity(ResultStatus.SUCCESS, Constants.QUERY_SUCCESS).setInfo(chartsVo);
	}

	@SuppressWarnings("unchecked")
	public ResultEntity singleYearDatasCharts(DatasChartsBo bo) {// 因子年数据
		String stationCode = bo.getStationCode();
		String factorCode = bo.getFactorCode();
		String startTime = bo.getStartTime();
		String endTime = bo.getEndTime();
		List<String> stationCodeList = ArrayUtils.stringToList(stationCode);
		List<String> factorCodeList = ArrayUtils.stringToList(factorCode); // 获取因子编码数据集
		// 初始化echarts实体
		ChartsVo chartsVo = new ChartsVo();
		List<String> xAxis = new ArrayList<String>(); // X轴数据集
		List<String> legend = new ArrayList<String>(); // 图例数据集
		List<Map<String, Object>> series = new ArrayList<Map<String, Object>>(); // 系列列表数据集
		// 获取年基础数据
		List<YearData> hourDataList = iYearDataRepository
				.findByStationCodeInAndFactorCodeInAndYearBetweenOrderByYearAsc(stationCodeList, factorCodeList,
						startTime, endTime);
		if (hourDataList == null || hourDataList.size() == 0) {
			return new ResultEntity(ResultStatus.SUCCESS, Constants.QUERY_SUCCESS);
		}
		ResultEntity projectResultEntity = iStieMangementService.queryProjectByProjectCode();
		Map<String, Project> projectMap = null;
		if (projectResultEntity.getCode() == 0) {
			projectMap = (Map<String, Project>) ((Map<String, Project>) projectResultEntity.getContent()).get("info");
		}
		// 获取初始时间数据集(需要与查询出来的时间数据集进行匹配对数值补null)
		List<String> timeList = DateUtil.getTimeYear(startTime, endTime);
		for (String code : factorCodeList) {
			String projectName = "";
			String projectUnit = "";
			if (projectMap != null) {
				Project project = MyBeanUtils.convertMapToBean((Map<String, Object>) projectMap.get(code),
						Project.class);
				projectName = project.getProjectName();
				projectUnit = project.getProjectUnit();
				String decimalDigits = project.getDecimalDigits() == null ? "3" : project.getDecimalDigits();
				xAxis = new ArrayList<String>(); // X轴数据集
				List<Double> data = new ArrayList<Double>(); // series中的data数据集
				Map<String, Object> seriesMap = new HashMap<String, Object>(); // series中的每个对象
				legend.add(projectName); // 需要存放因子名称
				xAxis = hourDataList.stream().filter(l -> code.equals(l.getFactorCode())).map(l -> l.getYear())
						.collect(Collectors.toList());
				data = hourDataList.stream().filter(l -> code.equals(l.getFactorCode()))
						.map(l -> Double.valueOf(ScaleUtil.sciCalProjectString(l.getDataValueAvg(), decimalDigits)))
						.collect(Collectors.toList());
				// 对数据进行null补值(某个时间点没有值)
				for (int i = 0; i < timeList.size(); i++) {
					if (!xAxis.contains(timeList.get(i))) {
						data.add(i, null);
					}
				}
				seriesMap.put("code", code);
				seriesMap.put("unit", projectUnit);
				seriesMap.put("name", projectName);
				seriesMap.put("data", data);
				seriesMap.put("type", "line");
				series.add(seriesMap);
			}
		}
		chartsVo.setLegend(legend);
		chartsVo.setxAxis(timeList);
		chartsVo.setSeries(series);
		return new ResultEntity(ResultStatus.SUCCESS, Constants.QUERY_SUCCESS).setInfo(chartsVo);
	}
	
	@SuppressWarnings({"unchecked","serial"})
	public ResultEntity singleWeekDatasCharts(DatasChartsBo bo) {// 单因子周数据
		String stationCode = bo.getStationCode();
		String factorCode = bo.getFactorCode();
		String startTime = bo.getStartTime();//yyyy-MM-dd
		String endTime = bo.getEndTime();//yyyy-MM-dd
		List<String> stationCodeList = ArrayUtils.stringToList(stationCode);
		List<String> factorCodeList = ArrayUtils.stringToList(factorCode); // 获取因子编码数据集
		Date startDate = DateUtil.stringToDate(bo.getStartTime(), DateUtil.DATE_SMALL_STR);
		Date endDate = DateUtil.stringToDate(bo.getEndTime(), DateUtil.DATE_SMALL_STR);
		// 初始化echarts实体
		ChartsVo chartsVo = new ChartsVo();
		List<String> xAxis = new ArrayList<String>(); // X轴数据集
		List<String> legend = new ArrayList<String>(); // 图例数据集
		List<Map<String, Object>> series = new ArrayList<Map<String, Object>>(); // 系列列表数据集
		// 获取周基础数据
		List<WeekData> hourDataList = iWeekDataRespository.findAll(new Specification<WeekData>() {
			public Predicate toPredicate(Root<WeekData> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
				List<Predicate> predicates = new ArrayList<Predicate>();
				predicates.add(criteriaBuilder.greaterThanOrEqualTo(root.get("beginTime"), startDate));
				predicates.add(criteriaBuilder.lessThanOrEqualTo(root.get("endTime"), endDate));
				predicates.add(root.get("factorCode").in(factorCodeList));
				predicates.add(root.get("stationCode").in(stationCodeList));
				return query.where(predicates.toArray(new Predicate[predicates.size()]))
						.orderBy(criteriaBuilder.asc(root.get("beginTime"))).getRestriction();
			}
		});
//		List<WeekData> hourDataList = iWeekDataRespository
//				.findByStationCodeInAndFactorCodeInAndBeginTimeIsAfterAndEndTimeIsBeforeOrderByBeginTimeAsc
//				(stationCodeList, factorCodeList,
//						startDate, endDate);
		if (hourDataList == null || hourDataList.size() == 0) {
			return new ResultEntity(ResultStatus.SUCCESS, Constants.QUERY_SUCCESS);
		}
		ResultEntity projectResultEntity = iStieMangementService.queryProjectByProjectCode();
		Map<String, Project> projectMap = null;
		if (projectResultEntity.getCode() == 0) {
			projectMap = (Map<String, Project>) ((Map<String, Project>) projectResultEntity.getContent()).get("info");
		}
		// 获取初始时间数据集(需要与查询出来的时间数据集进行匹配对数值补null)
		List<String> timeList = DateUtil.getYearWeek(startTime,endTime);
		for (String code : factorCodeList) {
			String projectName = "";
			String projectUnit = "";
			if (projectMap != null) {
				Project project = MyBeanUtils.convertMapToBean((Map<String, Object>) projectMap.get(code),
						Project.class);
				projectName = project.getProjectName();
				projectUnit = project.getProjectUnit();
				String decimalDigits = project.getDecimalDigits() == null ? "3" : project.getDecimalDigits();
				xAxis = new ArrayList<String>(); // X轴数据集
				List<Double> data = new ArrayList<Double>(); // series中的data数据集
				Map<String, Object> seriesMap = new HashMap<String, Object>(); // series中的每个对象
				legend.add(projectName); // 需要存放因子名称
				xAxis = hourDataList.stream().filter(l -> code.equals(l.getFactorCode()))
						.map(l -> DateUtil.getMonthWeekString(DateUtil.dateToString(l.getBeginTime(), DateUtil.DATE_SMALL_STR)))
						.collect(Collectors.toList());
				data = hourDataList.stream().filter(l -> code.equals(l.getFactorCode()))
						.map(l -> Double.valueOf(ScaleUtil.sciCalProjectString(l.getDataValueAvg(), decimalDigits)))
						.collect(Collectors.toList());
				// 对数据进行null补值(某个时间点没有值)
				for (int i = 0; i < timeList.size(); i++) {
					if (!xAxis.contains(timeList.get(i))) {
						data.add(i, null);
					}
				}
				seriesMap.put("code", code);
				seriesMap.put("unit", projectUnit);
				seriesMap.put("name", projectName);
				seriesMap.put("data", data);
				seriesMap.put("type", "line");
				series.add(seriesMap);
			}
		}
		chartsVo.setLegend(legend);
		chartsVo.setxAxis(timeList);
		chartsVo.setSeries(series);
		return new ResultEntity(ResultStatus.SUCCESS, Constants.QUERY_SUCCESS).setInfo(chartsVo);
	}

	@SuppressWarnings("unchecked")
	public ResultEntity queryRowToColHourDataCharts(String stationCode,String factorCode, String startTime, String endTime, String isNnusual) throws IOException {
		QueryParamDto queryParamDto = JsonUtils.readJsonFromClassPath("/param/siteQuery.json", QueryParamDto.class);
		ResultEntity resultStation = iStieMangementService.queryStation(queryParamDto);
		Map<String, Object> dataMap = (Map<String, Object>)resultStation.getContent();
		List<Map<String, Object>> siteList = (List<Map<String, Object>>)dataMap.get("dataList");
		Map<String, Map<String, Object>> siteMap = new HashMap<>();
		for(Map<String, Object> map:siteList) {
			siteMap.put(map.get("stationMn").toString(), map);
		}
		// 初始化echarts实体
		ChartsVo chartsVo = new ChartsVo();
		List<String> xAxis = new ArrayList<String>(); // X轴数据集
		List<String> legend = new ArrayList<String>(); // 图例数据集
		List<Map<String, Object>> series = new ArrayList<Map<String, Object>>(); // 系列列表数据集
		// 获取小时基础数据
		ResultEntity resultEntity = iDataReceivingService.queryHourDatas(stationCode, factorCode, startTime, endTime);
		List<HourData> hourDataList = ObjectMapperUtil.convertList(resultEntity, HourData.class);
		if (hourDataList == null || hourDataList.size() == 0) {
			return new ResultEntity(ResultStatus.SUCCESS, Constants.QUERY_SUCCESS);
		}
		//过滤异常数据
		List<HourData> all = new ArrayList<HourData>();
		List<HourData> normal = new ArrayList<HourData>();
		List<HourData> unusual = new ArrayList<HourData>();
		for (HourData hourData : hourDataList) {
			String mn = hourData.getMn();
			String targertArm = siteMap.get(mn).get("targerWaterQuality").toString();
			int armLevel = NumberUtils.createInteger(WaterLevelUtils.exchangeWaterLevelToNumber(targertArm));
			int level = WaterQualityUtil.getWaterLevel(hourData.getFactorCode(), hourData.getValue());
			if (armLevel>=level) {
				normal.add(hourData);
			}else {
				unusual.add(hourData);
			}
			all.add(hourData);
		}
		if (isNnusual.equals("all")) {
			hourDataList = all;
		}else if (isNnusual.equals("normal")) {
			hourDataList = normal;
		}else {
			hourDataList = unusual;
		}
		//
		List<String> factorCodeList = ArrayUtils.stringToList(factorCode); // 获取因子编码数据集
		ResultEntity projectResultEntity = iStieMangementService.queryProjectByProjectCode();
		Map<String, Project> projectMap = null;
		if (projectResultEntity.getCode() == 0) {
			projectMap = (Map<String, Project>) ((Map<String, Project>) projectResultEntity.getContent()).get("info");
		}
		// 获取初始时间数据集(需要与查询出来的时间数据集进行匹配对数值补null)
		List<String> timeList = DateUtil.getTimeList(startTime, endTime, DateUtil.DATE_SMALL_YMDHH, "hour");
		for (String code : factorCodeList) {
			String projectName = "";
			String projectUnit = "";
			if (projectMap != null) {
				Project project = MyBeanUtils.convertMapToBean((Map<String, Object>) projectMap.get(code),
						Project.class);
				projectName = project.getProjectName();
				projectUnit = project.getProjectUnit();
				String decimalDigits = project.getDecimalDigits() == null ? "3" : project.getDecimalDigits();// 数据修约位数默认为3
				xAxis = new ArrayList<String>(); // X轴数据集
				List<Double> data = new ArrayList<Double>(); // series中的data数据集
				Map<String, Object> seriesMap = new HashMap<String, Object>(); // series中的每个对象
				legend.add(projectName); // 需要存放因子名称
				xAxis = hourDataList.stream().filter(l -> code.equals(l.getFactorCode()))
						.map(l -> DateUtil.dateToString(l.getDataTime(), DateUtil.DATE_SMALL_YMDHH))
						.collect(Collectors.toList());
				data = hourDataList.stream().filter(l -> code.equals(l.getFactorCode()))
						.map(l -> Double.valueOf(ScaleUtil.sciCalProjectString(l.getValue(), decimalDigits)))
						.collect(Collectors.toList());
				// 对数据进行null补值(某个时间点没有值)
				for (int i = 0; i < timeList.size(); i++) {
					if (!xAxis.contains(timeList.get(i))) {
						data.add(i, null);
					}
				}
				seriesMap.put("code", code);
				seriesMap.put("name", projectName);
				seriesMap.put("unit", projectUnit);
				seriesMap.put("data", data);
				seriesMap.put("type", "line");
				series.add(seriesMap);
			}
		}
		chartsVo.setLegend(legend);
		chartsVo.setxAxis(timeList);
		chartsVo.setSeries(series);
		return new ResultEntity(ResultStatus.SUCCESS, Constants.QUERY_SUCCESS).setInfo(chartsVo);
	}
}
